package calcmaster.calculator.util;

import java.util.EnumMap;

import calcmaster.calculator.domain.Function;
import calcmaster.calculator.domain.FunctionType;
import calcmaster.calculator.functions.AbsFunction;
import calcmaster.calculator.functions.ArccosFunction;
import calcmaster.calculator.functions.ArccoshFunction;
import calcmaster.calculator.functions.ArcctgFunction;
import calcmaster.calculator.functions.ArcctghFunction;
import calcmaster.calculator.functions.ArctgFunction;
import calcmaster.calculator.functions.ArctghFunction;
import calcmaster.calculator.functions.CeilFunction;
import calcmaster.calculator.functions.CosFunction;
import calcmaster.calculator.functions.CoshFunction;
import calcmaster.calculator.functions.CtgFunction;
import calcmaster.calculator.functions.CtghFunction;
import calcmaster.calculator.functions.DivFunction;
import calcmaster.calculator.functions.DtogFunction;
import calcmaster.calculator.functions.DtorFunction;
import calcmaster.calculator.functions.ExpFunction;
import calcmaster.calculator.functions.FloorFunction;
import calcmaster.calculator.functions.FracFunction;
import calcmaster.calculator.functions.GtodFunction;
import calcmaster.calculator.functions.GtorFunction;
import calcmaster.calculator.functions.LgFunction;
import calcmaster.calculator.functions.LnFunction;
import calcmaster.calculator.functions.LogFunction;
import calcmaster.calculator.functions.MaxFunction;
import calcmaster.calculator.functions.MinFunction;
import calcmaster.calculator.functions.ModFunction;
import calcmaster.calculator.functions.RandFunction;
import calcmaster.calculator.functions.RandomnFunction;
import calcmaster.calculator.functions.RandomrFunction;
import calcmaster.calculator.functions.RoundFunction;
import calcmaster.calculator.functions.RtodFunction;
import calcmaster.calculator.functions.RtogFunction;
import calcmaster.calculator.functions.SinFunction;
import calcmaster.calculator.functions.SinhFunction;
import calcmaster.calculator.functions.SqrtFunction;
import calcmaster.calculator.functions.TgFunction;
import calcmaster.calculator.functions.TghFunction;
import calcmaster.calculator.functions.TruncFunction;

public class FunctionRepository {
	private EnumMap<FunctionType, Function> functionMap;
	
	private static FunctionRepository instance = new FunctionRepository();
	
	private FunctionRepository() {
		functionMap = new EnumMap<FunctionType, Function>(FunctionType.class);
		
		functionMap.put(FunctionType.ABS, new AbsFunction());
		functionMap.put(FunctionType.ARCCOS, new ArccosFunction());
		functionMap.put(FunctionType.ARCCOSH, new ArccoshFunction());
		functionMap.put(FunctionType.ARCCTG, new ArcctgFunction());
		functionMap.put(FunctionType.ARCCTGH, new ArcctghFunction());
		functionMap.put(FunctionType.ARCSIN, new AbsFunction());
		functionMap.put(FunctionType.ARCSINH, new ArccoshFunction());
		functionMap.put(FunctionType.ARCTG, new ArctgFunction());
		functionMap.put(FunctionType.ARCTGH, new ArctghFunction());
		functionMap.put(FunctionType.CEIL, new CeilFunction());
		functionMap.put(FunctionType.COS, new CosFunction());
		functionMap.put(FunctionType.COSH, new CoshFunction());
		functionMap.put(FunctionType.CTG, new CtgFunction());
		functionMap.put(FunctionType.CTGH, new CtghFunction());
		functionMap.put(FunctionType.DIV, new DivFunction());
		functionMap.put(FunctionType.DTOG, new DtogFunction());
		functionMap.put(FunctionType.DTOR, new DtorFunction());
		functionMap.put(FunctionType.EXP, new ExpFunction());
		functionMap.put(FunctionType.FLOOR, new FloorFunction());
		functionMap.put(FunctionType.FRAC, new FracFunction());
		functionMap.put(FunctionType.GTOD, new GtodFunction());
		functionMap.put(FunctionType.GTOR, new GtorFunction());
		functionMap.put(FunctionType.LG, new LgFunction());
		functionMap.put(FunctionType.LN, new LnFunction());
		functionMap.put(FunctionType.LOG, new LogFunction());
		functionMap.put(FunctionType.MAX, new MaxFunction());
		functionMap.put(FunctionType.MIN, new MinFunction());
		functionMap.put(FunctionType.MOD, new ModFunction());
		functionMap.put(FunctionType.RAND, new RandFunction());
		functionMap.put(FunctionType.RANDOM, new RandomnFunction());
		functionMap.put(FunctionType.RANDOMR, new RandomrFunction());
		functionMap.put(FunctionType.ROUND, new RoundFunction());
		functionMap.put(FunctionType.RTOD, new RtodFunction());
		functionMap.put(FunctionType.RTOG, new RtogFunction());
		functionMap.put(FunctionType.SIN, new SinFunction());
		functionMap.put(FunctionType.SINH, new SinhFunction());
		functionMap.put(FunctionType.SQRT, new SqrtFunction());
		functionMap.put(FunctionType.TG, new TgFunction());
		functionMap.put(FunctionType.TGH, new TghFunction());
		functionMap.put(FunctionType.TRUNC, new TruncFunction());
	}
	
	public static FunctionRepository getInstance() {
		return instance;
	}
	
	public boolean isFunctionListed(String functionName) {
		FunctionType functionType = FunctionType.getFromName(functionName);
		
		return (functionMap.get(functionType) != null);
	}
	
	public Function getFunction(FunctionType functionType) {
		return functionMap.get(functionType);
	}

}
